--- lib/geom/eli/geom_eli.c.orig
+++ lib/geom/eli/geom_eli.c
@@ -571,27 +571,35 @@
 	return (0);
 }
 
-static unsigned char *
-eli_genkey(struct gctl_req *req, struct g_eli_metadata *md, unsigned char *key,
-    bool new)
+static bool
+eli_init_key_hmac_ctx(struct gctl_req *req, struct hmac_ctx *ctx, bool new)
 {
-	struct hmac_ctx ctx;
-	bool nopassphrase;
 	int nfiles;
+	bool nopassphrase;
 
 	nopassphrase =
 	    gctl_get_int(req, new ? "nonewpassphrase" : "nopassphrase");
 
-	g_eli_crypto_hmac_init(&ctx, NULL, 0);
-
-	nfiles = eli_genkey_files(req, new, "keyfile", &ctx, NULL, 0);
-	if (nfiles == -1)
-		return (NULL);
-	else if (nfiles == 0 && nopassphrase) {
+	g_eli_crypto_hmac_init(ctx, NULL, 0);
+	nfiles = eli_genkey_files(req, new, "keyfile", ctx, NULL, 0);
+	if (nfiles == -1) {
+		return (false);
+	} else if (nfiles == 0 && nopassphrase) {
 		gctl_error(req, "No key components given.");
-		return (NULL);
+		return (false);
 	}
 
+	return (true);
+}
+
+static unsigned char *
+eli_genkey(struct gctl_req *req, const struct hmac_ctx *ctxtemplate,
+    struct g_eli_metadata *md, unsigned char *key, bool new)
+{
+	struct hmac_ctx ctx;
+
+	memcpy(&ctx, ctxtemplate, sizeof(ctx));
+
 	if (eli_genkey_passphrase(req, md, new, &ctx) == -1)
 		return (NULL);
 
@@ -600,6 +608,22 @@
 	return (key);
 }
 
+static unsigned char *
+eli_genkey_single(struct gctl_req *req, struct g_eli_metadata *md,
+		  unsigned char *key, bool new)
+{
+	struct hmac_ctx ctx;
+	unsigned char *rkey;
+
+	if (!eli_init_key_hmac_ctx(req, &ctx, new)) {
+		return (NULL);
+	}
+	rkey = eli_genkey(req, &ctx, md, key, new);
+	explicit_bzero(&ctx, sizeof(ctx));
+
+	return (rkey);
+}
+
 static int
 eli_metadata_read(struct gctl_req *req, const char *prov,
     struct g_eli_metadata *md)
@@ -711,6 +735,7 @@
 	intmax_t val;
 	int error, i, nargs, nparams, param;
 	const int one = 1;
+	struct hmac_ctx ctxtemplate;
 
 	nargs = gctl_get_int(req, "nargs");
 	if (nargs <= 0) {
@@ -844,6 +869,10 @@
 	 */
 	nparams = req->narg - nargs - 1;
 
+	/* Generate HMAC context template. */
+	if (!eli_init_key_hmac_ctx(req, &ctxtemplate, true))
+		return;
+
 	/* Create new child request for each provider and issue to kernel */
 	for (i = 0; i < nargs; i++) {
 		r = gctl_get_handle();
@@ -885,7 +914,7 @@
 		arc4random_buf(md.md_mkeys, sizeof(md.md_mkeys));
 
 		/* Generate user key. */
-		if (eli_genkey(r, &md, key, true) == NULL) {
+		if (eli_genkey(r, &ctxtemplate, &md, key, true) == NULL) {
 			/*
 			 * Error generating key - details added to geom request
 			 * by eli_genkey().
@@ -1009,6 +1038,7 @@
 
 	/* Clear the cached metadata, including keys. */
 	explicit_bzero(&md, sizeof(md));
+	explicit_bzero(&ctxtemplate, sizeof(ctxtemplate));
 }
 
 static void
@@ -1020,6 +1050,7 @@
 	off_t mediasize;
 	int i, nargs, nparams, param;
 	const int one = 1;
+	struct hmac_ctx ctxtemplate;
 
 	nargs = gctl_get_int(req, "nargs");
 	if (nargs <= 0) {
@@ -1035,6 +1066,10 @@
 	 */
 	nparams = req->narg - nargs - 1;
 
+	/* Generate HMAC context template. */
+	if (!eli_init_key_hmac_ctx(req, &ctxtemplate, false))
+		return;
+
 	/* Create new child request for each provider and issue to kernel */
 	for (i = 0; i < nargs; i++) {
 		r = gctl_get_handle();
@@ -1064,7 +1099,7 @@
 			goto out;
 		}
 
-		if (eli_genkey(r, &md, key, false) == NULL) {
+		if (eli_genkey(r, &ctxtemplate, &md, key, false) == NULL) {
 			/*
 			 * Error generating key - details added to geom request
 			 * by eli_genkey().
@@ -1098,6 +1133,7 @@
 
 	/* Clear sensitive data from memory. */
 	explicit_bzero(cached_passphrase, sizeof(cached_passphrase));
+	explicit_bzero(&ctxtemplate, sizeof(ctxtemplate));
 }
 
 static void
@@ -1295,7 +1331,7 @@
 		old = md->md_iterations;
 
 	/* Generate key for Master Key encryption. */
-	if (eli_genkey(req, md, key, true) == NULL) {
+	if (eli_genkey_single(req, md, key, true) == NULL) {
 		explicit_bzero(key, sizeof(key));
 		return;
 	}
@@ -1330,7 +1366,7 @@
 	}
 
 	/* Generate key for Master Key decryption. */
-	if (eli_genkey(req, md, key, false) == NULL) {
+	if (eli_genkey_single(req, md, key, false) == NULL) {
 		explicit_bzero(key, sizeof(key));
 		return;
 	}
@@ -1388,7 +1424,7 @@
 	explicit_bzero(mkey, sizeof(mkey));
 
 	/* Generate key for Master Key encryption. */
-	if (eli_genkey(req, md, key, true) == NULL) {
+	if (eli_genkey_single(req, md, key, true) == NULL) {
 		explicit_bzero(key, sizeof(key));
 		explicit_bzero(md, sizeof(*md));
 		return;
@@ -1534,7 +1570,7 @@
 		return;
 	}
 
-	if (eli_genkey(req, &md, key, false) == NULL) {
+	if (eli_genkey_single(req, &md, key, false) == NULL) {
 		explicit_bzero(key, sizeof(key));
 		return;
 	}
